import {
	parseBLEData,
	onBLEConnectionStateChange
} from '@/utils/bleParser.js'
// bluetooth.js
const eventManager = require('./eventManager.js');

//固定硬件服务
const MY_DEVICE_SERVICE = {
	serviceId: '0000FFF0-0000-1000-8000-00805F9B34FB',
	readUuid: '0783B03E-8535-B5A0-7140-A304D2495CB8',
	writeUuid: '0783B03E-8535-B5A0-7140-A304D2495CBA',
}
const OTA_DEVICE_SERVICE = {
	serviceId: '02F00000-0000-0000-0000-00000000FE00',
	readUuid: '02F00000-0000-0000-0000-00000000FF02',
	writeUuid: '02F00000-0000-0000-0000-00000000FF01',
}

class BluetoothManager {
	constructor() {
		this.deviceId = null;
		this.serviceId = null;
		this.characteristicId = null;
		this.notifyState = 0;
		this.deviceMap = {}
	}

	// 初始化蓝牙模块
	initBluetooth() {
		return new Promise((resolve, reject) => {
			uni.openBluetoothAdapter({
				success: () => {
					console.log('Bluetooth Adapter initialized');
					resolve();
				},
				fail: (err) => {
					console.error('Failed to initialize Bluetooth Adapter', err);
					reject(err);
				}
			});
		});
	}

	onConnectionStateChange() {
		uni.onBLEConnectionStateChange(onBLEConnectionStateChange)
	}

	// 搜索蓝牙设备
	searchDevices(onDeviceFound) {
		return new Promise((resolve, reject) => {
			uni.startBluetoothDevicesDiscovery({
				success: () => {
					console.log('Started Bluetooth device discovery');
					// 监听发现新设备的事件
					uni.onBluetoothDeviceFound((result) => {
						onDeviceFound(result.devices);
					});
					this.onConnectionStateChange()
					resolve();
				},
				fail: (err) => {
					console.error('Failed to start Bluetooth device discovery', err);
					reject(err);
				}
			});
		});
	}

	// 蓝牙设备列表
	getBluetoothDevices() {
		return new Promise((resolve, reject) => {
			uni.getBluetoothDevices({
				success(res) {
					resolve(res);
				}
			})
		});

	}

	// 停止搜索蓝牙设备
	stopSearchDevices() {
		return new Promise((resolve, reject) => {
			uni.stopBluetoothDevicesDiscovery({
				success: () => {
					console.log('Stopped Bluetooth device discovery');
					resolve();
				},
				fail: (err) => {
					console.error('Failed to stop Bluetooth device discovery', err);
					reject(err);
				}
			});
		});
	}

	// 连接蓝牙设备
	connectToDevice(deviceId) {
		return new Promise((resolve, reject) => {
			uni.createBLEConnection({
				deviceId,
				success: () => {
					console.log('Connected to Bluetooth device');
					this.deviceId = deviceId;
					this.setBLEMTU(deviceId)
					resolve();
				},
				fail: (err) => {
					console.error('Failed to connect to Bluetooth device', err);
					reject(err);
				}
			});
		});
	}

	// 获取蓝牙设备的服务
	getDeviceServices() {
		return new Promise((resolve, reject) => {
			uni.getBLEDeviceServices({
				deviceId: this.deviceId,
				success: (res) => {
					console.log('Got Bluetooth device services', res.services);
					this.serviceId = res.services[0].uuid; // 假设使用第一个服务
					resolve(res.services);
				},
				fail: (err) => {
					console.error('Failed to get Bluetooth device services', err);
					reject(err);
				}
			});
		});
	}

	// 获取蓝牙设备服务的特征值
	getDeviceCharacteristics(deviceId, serviceId) {
		return new Promise((resolve, reject) => {
			uni.getBLEDeviceCharacteristics({
				deviceId: deviceId,
				serviceId: serviceId,
				success: (res) => {
					console.log('Got Bluetooth device characteristics', res.characteristics);
					this.characteristicId = res.characteristics[0].uuid; // 假设使用第一个特征值
					resolve(res.characteristics);
				},
				fail: (err) => {
					console.error('Failed to get Bluetooth device characteristics', err);
					reject(err);
				}
			});
		});
	}

	//对外统一链接服务
	connectToDeviceForSanLi(deviceId) {
		return new Promise(async (resolve, reject) => {
			try {
				await this.connectToDevice(deviceId)
				if (this.notifyState == 0) {
					console.log('通知开启')
					uni.onBLECharacteristicValueChange(function(res) {
						console.log(
							`characteristic ${res.characteristicId} has changed, now is ${res.value}`
						)
						if (res.characteristicId == MY_DEVICE_SERVICE.readUuid) {
							parseBLEData(res)
						}
						if (res.characteristicId == OTA_DEVICE_SERVICE.readUuid) {
							eventManager.emitEvent('onBLECharacteristicValueChangeOta', res)
						}
					})
					this.notifyState = 1
				}
				const services = await this.getDeviceServices()
				for (let i = 0; i < services.length; i++) {
					if (services[i].isPrimary) {
						const characteristics = await this.getDeviceCharacteristics(deviceId, services[
							i].uuid)
						this.startCharacteristicsNotify(deviceId, services[i].uuid, characteristics)
					}
				}
				resolve();
			} catch (err) {
				console.error('Failed to get Bluetooth device characteristics', err);
				reject(err)
			}
		})
	}

	startCharacteristicsNotify(deviceId, serviceId, characteristics) {
		for (let i = 0; i < characteristics.length; i++) {
			let item = characteristics[i]
			//设备基础服务监听
			if (item.uuid == MY_DEVICE_SERVICE.readUuid) {
				uni.notifyBLECharacteristicValueChange({
					deviceId,
					serviceId,
					characteristicId: MY_DEVICE_SERVICE.readUuid,
					state: true,
					success: (res) => {
						this.sendCommand(deviceId, serviceId, MY_DEVICE_SERVICE.writeUuid, 0x01, [0x01])
						eventManager.emitEvent('notifyBLECharacteristicOk', res)
					},
					fail: (res) => {
						console.log('notifyBLECharacteristicValueChange_fail', res)
					}
				})
			}
			//设备ota监听
			if (item.uuid == OTA_DEVICE_SERVICE.readUuid) {
				uni.notifyBLECharacteristicValueChange({
					deviceId,
					serviceId,
					characteristicId: OTA_DEVICE_SERVICE.readUuid,
					state: true,
					success: (res) => {
						console.log('notifyBLECharacteristicOtaOk')
						eventManager.emitEvent('notifyBLECharacteristicOtaOk', res)
					},
					fail: (res) => {
						console.log('notifyBLECharacteristicValueChange_fail', res)
					}
				})
			}
		}

	}

	sendCommand(deviceId, serviceId, characteristicId, cmd, data, head) {
		if (!head) {
			head = 0x79
		}
		var packet = [head, data.length + 1, cmd].concat(data)
		packet.push(this.calculateChecksum(packet));
		var buffer = new ArrayBuffer(packet.length)
		var dataView = new DataView(buffer);
		for (var i = 0; i < packet.length; i++) {
			dataView.setUint8(i, packet[i]);
		}
		return new Promise((resolve, reject) => {
			uni.writeBLECharacteristicValue({
				deviceId: deviceId,
				serviceId: serviceId,
				characteristicId: characteristicId,
				value: buffer,
				success: () => {
					console.log('发送成功')
					resolve()
				},
				fail: (err) => {
					console.error('发送失败', err)
					reject(err)
				}
			})
		})

	}

	sendOtaCommand(deviceId, serviceId, characteristicId, buffer) {
		return new Promise((resolve, reject) => {
			uni.writeBLECharacteristicValue({
				deviceId: deviceId,
				serviceId: serviceId,
				characteristicId: characteristicId,
				value: buffer,
				success: () => {
					console.log('ota发送成功')
					resolve()
				},
				fail: (err) => {
					console.error('ota发送失败', err)
					reject(err)
				}
			})
		})
	}

	calculateChecksum(data) {
		var checksum = 0;
		for (var i = 0; i < data.length; i++) {
			checksum += data[i];
		}
		let tmp = checksum
		// checksum = (~(checksum & 0xFF) + 1) & 0xFF;
		checksum = (checksum & 0xFF);
		checksum = (~checksum + 1) & 0xFF;
		// console.log("检查:" + tmp + "check:" + checksum + "结果:" + (checksum + tmp))
		return checksum;
	}

	// 发送信息到蓝牙设备
	sendMessage(message) {
		const buffer = new ArrayBuffer(message.length);
		const dataView = new DataView(buffer);
		for (let i = 0; i < message.length; i++) {
			dataView.setUint8(i, message.charCodeAt(i));
		}

		return new Promise((resolve, reject) => {
			uni.writeBLECharacteristicValue({
				deviceId: this.deviceId,
				serviceId: this.serviceId,
				characteristicId: this.characteristicId,
				value: buffer,
				success: () => {
					console.log('Message sent to Bluetooth device');
					resolve();
				},
				fail: (err) => {
					console.error('Failed to send message to Bluetooth device', err);
					reject(err);
				}
			});
		});
	}

	// 接收蓝牙设备的信息
	receiveMessage(callback) {
		uni.onBLECharacteristicValueChange((res) => {
			const receivedData = String.fromCharCode.apply(null, new Uint8Array(res.value));
			console.log('Received data from Bluetooth device', receivedData);
			callback(receivedData);
		});

		uni.notifyBLECharacteristicValueChange({
			deviceId: this.deviceId,
			serviceId: this.serviceId,
			characteristicId: this.characteristicId,
			state: true,
			success: () => {
				console.log('Enabled notify for receiving data from Bluetooth device');
			},
			fail: (err) => {
				console.error('Failed to enable notify for receiving data from Bluetooth device', err);
			}
		});
	}

	// setBLEMTU
	setBLEMTU(deviceId) {
		return new Promise((resolve, reject) => {
			uni.setBLEMTU({
				deviceId: deviceId,
				mtu: 512,
				success: () => {
					console.log('setBLEMTU success')
					resolve();
				},
				fail: (err) => {
					console.log('setBLEMTU error')
					reject(err)
				},
			})
		})
	}
	// 断开蓝牙连接
	disconnect(deviceId) {
		return new Promise((resolve, reject) => {
			uni.closeBLEConnection({
				deviceId: deviceId,
				success: () => {
					console.log('Disconnected from Bluetooth device');
					resolve();
				},
				fail: (err) => {
					console.error('Failed to disconnect from Bluetooth device', err);
					reject(err);
				}
			});
		});
	}
}

export default new BluetoothManager();